﻿using System;

namespace NodeJS
{
    using net;
    public abstract class Net
    {
        /// <summary>
        /// Creates a new TCP server.
        /// </summary>
        /// <param name="connectionListener"></param>
        /// <returns></returns>
        public abstract Server CreateServer(Action<Socket> connectionListener);

        /// <summary>
        /// Creates a new TCP server.
        /// </summary>
        /// <param name="options"></param>
        /// <param name="connectionListener">The connectionListener argument is automatically set as a listener for the 'connection' event.</param>
        /// <returns></returns>
        public abstract Server CreateServer(object options = null, Action<Socket> connectionListener = null);

        /// <summary>
        /// Constructs a new socket object and opens the socket to the given location. When the socket is established, the 'connect' event will be emitted.
        /// </summary>
        /// <param name="options">
        /// *For TCP sockets, options argument should be an object which specifies:
        /// <para>port: Port the client should connect to (Required).</para>
        /// <para>host: Host the client should connect to. Defaults to 'localhost'.</para>
        /// <para>localAddress: Local interface to bind to for network connections.</para>
        /// *For UNIX domain sockets, options argument should be an object which specifies:
        /// <para>path: Path the client should connect to (Required).</para>
        /// *Common options are:
        /// <para>allowHalfOpen: if true, the socket won't automatically send a FIN packet when the other end of the socket sends a FIN packet. Defaults to false. See 'end' event for more information.</para>
        /// </param>
        /// <param name="connectionListener">The connectListener parameter will be added as an listener for the 'connect' event.</param>
        /// <returns></returns>
        public abstract Socket Connect(object options, Action connectionListener = null);

        /// <summary>
        /// Constructs a new socket object and opens the socket to the given location. When the socket is established, the 'connect' event will be emitted.
        /// </summary>
        /// <param name="options">
        /// *For TCP sockets, options argument should be an object which specifies:
        /// <para>port: Port the client should connect to (Required).</para>
        /// <para>host: Host the client should connect to. Defaults to 'localhost'.</para>
        /// <para>localAddress: Local interface to bind to for network connections.</para>
        /// *For UNIX domain sockets, options argument should be an object which specifies:
        /// <para>path: Path the client should connect to (Required).</para>
        /// *Common options are:
        /// <para>allowHalfOpen: if true, the socket won't automatically send a FIN packet when the other end of the socket sends a FIN packet. Defaults to false. See 'end' event for more information.</para>
        /// </param>
        /// <param name="connectionListener">The connectListener parameter will be added as an listener for the 'connect' event.</param>
        /// <returns></returns>
        public abstract Socket CreateConnection(object options, Action connectionListener = null);

        /// <summary>
        /// Creates a TCP connection to port on host.
        /// </summary>
        /// <param name="port"></param>
        /// <param name="host">If host is omitted, 'localhost' will be assumed.</param>
        /// <param name="connectListener">The connectListener parameter will be added as an listener for the 'connect' event.</param>
        /// <returns></returns>
        public abstract Socket Connect(int port, string host = "localhost", Action connectListener = null);

        /// <summary>
        /// Creates a TCP connection to port on host.
        /// </summary>
        /// <param name="port"></param>
        /// <param name="host">If host is omitted, 'localhost' will be assumed.</param>
        /// <param name="connectListener">The connectListener parameter will be added as an listener for the 'connect' event.</param>
        /// <returns></returns>
        public abstract Socket CreateConnection(int port, string host = "localhost", Action connectListener = null);

        /// <summary>
        /// Creates unix socket connection to path.
        /// </summary>
        /// <param name="path"></param>
        /// <param name="connectListener">The connectListener parameter will be added as an listener for the 'connect' event.</param>
        /// <returns></returns>
        public abstract Socket Connect(string path, Action connectListener = null);

        /// <summary>
        /// Creates unix socket connection to path.
        /// </summary>
        /// <param name="path"></param>
        /// <param name="connectListener">The connectListener parameter will be added as an listener for the 'connect' event.</param>
        /// <returns></returns>
        public abstract Socket CreateConnection(string path, Action connectListener = null);

        /// <summary>
        /// Tests if input is an IP address.
        /// </summary>
        /// <param name="input"></param>
        /// <returns>
        /// <para>Returns 0 for invalid strings.</para>
        /// <para>returns 4 for IP version 4 addresses.</para>
        /// <para>returns 6 for IP version 6 addresses.</para>
        /// </returns>
        public abstract int IsIP(string input);

        /// <summary>
        /// Returns true if input is a version 4 IP address, otherwise returns false.
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public abstract bool IsIPv4(string input);

        /// <summary>
        /// Returns true if input is a version 6 IP address, otherwise returns false.
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public abstract bool IsIPv6(string input);
    }
}
